/*
 * @Author: yedi
 * @Date: 2021-11-11 20:14:40
 * @Last Modified by: yedi
 * @Last Modified time: 2022-07-12 14:46:43
 * @Last Content: 网络层封装
 */
// eslint-disable-next-line import/no-cycle
import { userLogin, loginFn, clearLoninData } from '@/utils/login'
import { Encrypt, Decrypt } from '@/utils/httpAes'

const hexMD5 = require('uview-ui/libs/function/md5.js')
const utils = require('@/utils/util.js')
const saveData = require('./storage.js')
const config = require('./config.js')
const Base64 = require('./base64.js')

// const code = {
//   SUCCESS: 10000,
//   FAILE: 10001,
//   USER_NOT_EXIST: 10008, // 用户不存在
//   RESULT_TOKEN_ERROR: 10301
// }
const httpAesWhiteUrls = ['https://restapi.amap.com/v3/geocode/regeo']
// const iPhone = uni.getSystemInfoSync().osName
const baseURL = ''
let aesDataType = '1'
const salt = uni.getStorageSync('salt')
let tokenKey = salt || ''
const { envVersion } = utils.getRunEnvFun()
let netInfo = ''
uni.getNetworkType({
  success(res) {
    netInfo = res.networkType
  }
})
// const baseURL = 'http://test-mp.jryghq.com'
// const baseURL = 'https://app-m.jryghq.com'//
// 传参：methods请求方法，params参数，urls接口，isFormData参数格式是否FormData，header请求头
const Http = async (methods = 'post', params, urls, isFormData = false, header, num = 3) => {
  let newParams = {}
  const url = baseURL + urls
  //  判断参数是否是form-data
  if (params && isFormData) {
    newParams = new window.FormData()
    // eslint-disable-next-line
    for (const i in params) {
      newParams.append(i, params[i])
    }
  } else {
    newParams = params || {}
  }

  // const nonce = new Date().getTime().toString()
  // newParams.nonce = nonce
  const diffTime = uni.getStorageSync('timeDiff') && uni.getStorageSync('timeDiff') !== 'undefined' ? Number(uni.getStorageSync('timeDiff')) : 0
  newParams.differ = diffTime || 0
  newParams.nonce = Date.now() + diffTime || 0
  // eslint-disable-next-line no-use-before-define
  const sign = getSign(newParams, header ? header['content-type'] : '')

  if (!tokenKey) {
    tokenKey = uni.getStorageSync('salt') || ''
    if (!tokenKey) uni.removeStorageSync('token')
  }

  // eslint-disable-next-line no-use-before-define
  const newHeader = getHeader(header, sign, aesDataType)
  // const tingyunParams = JSON.parse(JSON.stringify(newParams))
  // if (params && params.apiPathName) {
  //   delete newParams.apiPathName
  // }
  // console.log('newParamsnewParams', JSON.stringify(newParams), urls)
  const isBaseKeyEnv = urls.includes('dev') || urls.includes('test')
  const whiteBlo = httpAesWhiteUrls.includes(urls)
  let newParamss = ''
  if (whiteBlo || aesDataType === '0') {
    console.log('不加密')
  } else {
    const blo = newHeader['content-type'].includes('json')
    if (methods.toUpperCase() === 'GET') {
      const encryData = Encrypt({ ...newParams }, tokenKey, blo ? 'json' : 'form', isBaseKeyEnv)
      newParamss = { data: encryData } // encodeURIComponent(
    } else if (blo) {
      newParamss = { data: Encrypt({ ...newParams }, tokenKey, '', isBaseKeyEnv) }
    } else {
      newParamss = {
        data: Encrypt({ ...newParams }, tokenKey, blo ? 'json' : 'form', isBaseKeyEnv)
      }
      // console.log('config.data', config.data)
    }
  }
  // 不同请求的判断  // 这里依据项目要求自行更改传参格式
  let response = '' // 请求的返回值
  try {
    const res = await uni.request({
      method: methods,
      url,
      data: newParamss || newParams,
      header: newHeader,
      // #ifdef MP-ALIPAY
      enableCookie: true
      // #endif
    })
    const MarkTab = {
      e: 'Encrypt-Status',
      v: 'Verify-Status',
      d: 'Data-Type'
    }
    const markTab = {
      e: 'encrypt-status',
      v: 'verify-status',
      d: 'data-type'
    }
    // #ifdef MP-WEIXIN
    // eslint-disable-next-line prefer-destructuring
    response = res[1]
    // markTab = {
    //   e: 'Encrypt-Status',
    //   v: 'Verify-Status',
    //   d: 'Data-Type'
    // }
    // #endif
    // #ifdef MP-ALIPAY
    // eslint-disable-next-line prefer-destructuring
    response = res[0] || res[1]
    // if (iPhone !== 'ios' || envVersion === 'develop') {
    // if (iPhone === 'ios' && envVersion === 'trial') {
    //   markTab = {
    //     e: 'Encrypt-Status',
    //     v: 'Verify-Status',
    //     d: 'Data-Type'
    //   }
    // }
    // }
    // #endif
    // console.log('responseresponseresponse', response, res)
    const d = response.header[markTab.d] || response.header[MarkTab.d]
    const v = response.header[markTab.v] || response.header[MarkTab.v]
    const e = response.header[markTab.e] || response.header[MarkTab.e]

    if (e === '1') {
      aesDataType = '0'
    }
    if (v === '1' || v === '2') {
      // 刷新token
      tokenKey = ''
      clearLoninData()
      uni.redirectTo({
        url: '/pages/userLogin/index'
      })
      // if (uni.getStorageSync('token')) {
      //   signOutFun()
      //   clearLoninData()
      // }
      // response.data = {
      //   code: 288,
      //   message: '登录失效,请重新登录~'
      // }
      // console.log('我草，失效了')
    }

    // console.log('哈哈哈', response.header['encrypt-status'], response.header['Encrypt-Status'])

    if ((d === '1' || d === '2') && v === '3') {
      const data = await Decrypt(response.data, d === '1' ? '' : tokenKey, isBaseKeyEnv)
      response.data = JSON.parse(data)
      // console.log('parse--response', response.data)
    }

    if (e === '2' && v === '3') {
      aesDataType = d === '2' && tokenKey ? '2' : '1'
    }
    // console.log('🚀 ~ file: request.js ~ line 28 ~ Http ~ response', response)
    if (urls.includes('v3/user/wxmini-sigin') || urls.includes('passengerApi/oauth/signIn')) tokenKey = response.data.data.salt
    // console.log('saltsaltsaltsalt', tokenKey, iPhone, markTab)
  } catch (err) {
    response = err
    // throw new Error(`url:${url}&&msg:${JSON.stringify(response)}`)
  }
  // response 这里直接return response的话,可以拿到返回的所有请求头数据,可以打印看看,然后根据自己项目需求进行判断
  // 有点麻烦的是这里的一串判断,因为没有拦截器
  if (response.data?.code * 1 === 29408 && num > 0) {
    const time = response.data.data.timeDiff + newParams.differ
    uni.setStorageSync('timeDiff', time)
    Http((methods = 'post'), params, urls, (isFormData = false), header, (num -= 1))
  }

  if (response?.data?.code * 1 === 11302) {
    uni.redirectTo({
      url: '/pages/userLogin/index'
    })
    return
  }

  if (response?.data?.code * 1 === 10301) {
    // {"code":10301,"message":"无效的 access_token"}
    // uni.showToast({
    //   icon: 'none',
    //   title: response.data.message,
    //   duration: 1000
    // })
    // #ifdef MP-ALIPAY
    if (!urls.includes('passengerApi/realOrder/estimateByTrip')) return
    loginFn()
    // #endif
    // #ifdef MP-WEIXIN
    await userLogin()
    return
    // #endif
  }
  // debugger 742 - 752 751 - 761
  // console.log('response.data', response)
  if (response?.data?.code * 1 === 10000 || response?.data?.code * 1 === 0 || response?.data?.infocode * 1 === 10000) {
    return response.data // 返回响应值
  }
sign
  // setTimeout(() => {
  //   throw new Error(`url:${url}&&msg:${JSON.stringify(response.data)}&&params:${JSON.stringify(tingyunParams)}`)
  // }, 100)

  return response.data // 返回响应值
}
/**
 * 获取UserAgent
 * @returns {*}
 */
export function getUserAgent() {
  /** 手机型号 */
  const { model, platform, system } = uni.$u.sys()
  const app = getApp()
  let channel = ''
  // #ifdef MP-WEIXIN
  channel = 'wx'
  // #endif
  // #ifdef MP-ALIPAY
  channel = 'alipay'
  // 新增广告位入口进入渠道
  // #endif
  if (app.globalData.shopChannel) {
    channel += `_${app.globalData.shopChannel}`
  }
  const appVersion = envVersion === 'develop' || envVersion === 'trial' ? '5.0.0' : app.globalData.appVersion
  return `YGSmallProgram/${appVersion}(${config.configObj.request_useragent_pre};${platform}${system};${model};${channel})`
}
/**
 * 头部Hint信息
 */
function getYGHeaderHintContent() {
  const app = getApp()
  // console.log('app', app)
  const openId = app.globalData.authId || app.globalData.oppenId || saveData.getData('openId') || ''

  const hindHeard = {
    city_id: `${app.globalData.location.cityId}`,
    loc_lat: app.globalData.location.lat,
    loc_lng: app.globalData.location.lng,
    loc_type: 'wgs',
    imei_uuid: '',
    device_no: openId, //  saveData.getData('TINGYUN_UID') || '',
    net_info: netInfo,
    timestamp_unix: '',
    app_timeout_ms: '30000',
    imsi: '',
    mac: '',
    net_type: '',
    mobileMerchant: '',
    auth_id: openId
  }
  return Base64.encode(JSON.stringify(hindHeard))
}

/**
 * 获取签名文件
 */
function getSign(params, val) {
  const parms = { ...params }
  let content = null
  if (val.includes('json')) {
    content = `${JSON.stringify(parms)}&key=${config.configObj.request_sign_key}`
    // console.log('contentcontent', content)
  } else {
    // eslint-disable-next-line no-restricted-syntax, guard-for-in
    for (const key in parms) {
      if (parms[key] === '') {
        delete parms[key]
      }
      // #ifdef MP-ALIPAY
      if (parms[key] === undefined) {
        delete parms[key]
      }
      // #endif
    }
    // console.log(parms)
    // eslint-disable-next-line no-array-constructor
    const keys = new Array()
    let index = 0
    // eslint-disable-next-line
    for (const key in parms) {
      keys[index] = key
      index++
    }
    keys.sort()
    for (let i = 0; i < keys.length; i++) {
      if (content) {
        content = `${content}&${keys[i]}=${parms[keys[i]]}`
      } else {
        content = `${keys[i]}=${parms[keys[i]]}`
      }
    }
    content = `${content}&key=${config.configObj.request_sign_key}`
  }
  // console.log('🚀 ~ file: request.js ~ line 151 ~ getSign ~ content222222', content)
  // content = `${content}&key=${config.configObj.request_sign_key}`
  return hexMD5.md5(content).toLocaleUpperCase()
}

/**
 * 头部签名
 * @param oldheader
 * @param sign
 * @returns {*}
 */
function getHeader(oldheader, sign, aesDataType) {
  const app = getApp()
  let uas = ''
  // #ifdef MP-WEIXIN
  uas = 'YGSmallProgram/5.10.0(wechatapp;androidAndroid 11;PDRM00;wx)'
  if (app.globalData.shopChannel) {
    uas = `YGSmallProgram/5.10.0(wechatapp;androidAndroid 11;PDRM00;wx_${app.globalData.shopChannel})`
  }
  // #endif

  // #ifdef MP-ALIPAY
  uas = 'YGSmallProgram/5.10.0(alipayapp;androidAndroid 11;PDRM00;alipay)'
  if (app.globalData.shopChannel) {
    uas = `YGSmallProgram/5.10.0(alipayapp;androidAndroid 11;PDRM00;alipay_${app.globalData.shopChannel})`
  }
  // #endif
  const ua = envVersion === 'develop' || envVersion === 'trial' ? uas : getUserAgent()
  let header = oldheader
  let cookie
  if (header) {
    cookie = `yg_access_token=${saveData.getToken()}`
    header.sign = sign
    header.Cookie = cookie
    header.YgUserAgent = ua
    // header.YgUserAgent = 'YGSmallProgram/2.3.0(wechatapp;androidAndroid 11;PDRM00;wx)'
    header['Accept-Language'] = 'zh-cn'
    header['Yg-Header-Hint-Content'] = getYGHeaderHintContent()
    header['data-type'] = aesDataType
    header['content-type'] = 'application/x-www-form-urlencoded; charset=UTF-8'
    // #ifdef MP-ALIPAY
    header.dataType = aesDataType !== 0 ? 'text' : 'json'
    // #endif
  } else {
    cookie = `yg_access_token=${saveData.getToken()}`
    header = {
      sign,
      Cookie: cookie,
      'content-type': 'application/x-www-form-urlencoded; charset=UTF-8',
      'Yg-Header-Hint-Content': getYGHeaderHintContent(),
      'Accept-Language': 'zh-cn',
      YgUserAgent: ua,
      'data-type': aesDataType,
      // #ifdef MP-ALIPAY
      dataType: aesDataType !== 0 ? 'text' : 'json'
      // #endif
    }
  }
  // console.log('🚀 ~ file: request.js ~ line 171 ~ getHeader ~ header', header)
  return header
}

export default Http
